
package it.csttech.date;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;

import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;

/**
 * This class is meant to marshal java objects into a JSON object
 * 
 * @author marcello.felappi
 * @author marco.dalena
 */
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class ObjectBodyWriter implements MessageBodyWriter<Object> {

	@Context
	HttpServletRequest request;

	@Override
	public boolean isWriteable(
		Class<?> cl, Type type, Annotation[] ann, MediaType media) {

		return true;
	}

	/**
	 * This method is used to marshal a java object "object" of class "cl" and
	 * Type "type" into a JSON object
	 * 
	 * @param Object
	 *            object - object to be written
	 * @param Class
	 *            cl - class of the object to be written
	 * @param Type
	 *            type - type of the object to be written
	 * @param Annotation
	 *            ann - annotations on the object
	 * @param MediaType
	 *            media - media type of the object
	 * @param MultivaluedMap
	 *            <String, String> multiMap - contains the header of the request
	 * @param OutputStream
	 *            output - output stream in which to write the data
	 */
	@Override
	public void writeTo(
		Object object, Class<?> cl, Type type, Annotation[] ann,
		MediaType media, MultivaluedMap<String, Object> multiMap,
		OutputStream output)
		throws IOException, WebApplicationException {

		ObjectMapper mapper = new ObjectMapper();

		DateJsonSerializer dateWriter =
			new DateJsonSerializer(request.getLocale());
		SimpleModule simpleDate =
			new SimpleModule("dateModule", new Version(
				0, 1, 0, "alpha", "groupId", "artifactId"));
		simpleDate.addSerializer(Date.class, dateWriter);
		mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
		mapper.registerModule(simpleDate);

		FloatJsonSerializer flwriter =
			new FloatJsonSerializer(request.getLocale());
		SimpleModule simpleFloat =
			new SimpleModule("floatModule", new Version(
				0, 1, 0, "alpha", "groupId", "artifactId"));
		simpleFloat.addSerializer(Float.class, flwriter);
		mapper.registerModule(simpleFloat);

		mapper.writeValue(output, object);
	}

	/**
	 * Method leaved unimplemented since it is depracated, as stated by Jersey
	 * 2.7 API
	 * 
	 * @deprecated
	 */
	@Override
	public long getSize(
		Object obj, Class<?> cl, Type type, Annotation[] ann, MediaType media) {

		return 0;
	}

}
